<?php


namespace wchat\common;


class Help extends Multiprogramming
{

	/**
	 * @param array $data
	 * @return string
	 */
	public static function toXml(array $data): string
	{
		$xml = "<xml>";
		foreach ($data as $key => $val) {
			if (is_array($val)) {
				$xml .= "<" . $key . ">" . static::xmlChild($val) . "</" . $key . ">";
				continue;
			}
			if (is_numeric($val)) {
				$xml .= "<" . $key . ">" . $val . "</" . $key . ">";
			} else {
				$xml .= "<" . $key . "><![CDATA[" . $val . "]]></" . $key . ">";
			}
		}
		$xml .= "</xml>";
		return $xml;
	}


	/**
	 * @param array $array
	 * @return string
	 */
	private static function xmlChild(array $array): string
	{
		$string = '';
		foreach ($array as $key => $value) {
			if (is_array($value)) {
				$string .= static::xmlChild($value);
				continue;
			}

			if (is_numeric($value)) {
				$string .= "<" . $key . ">" . $value . "</" . $key . ">";
			} else {
				$string .= "<" . $key . "><![CDATA[" . $value . "]]></" . $key . ">";
			}
		}
		return $string;
	}


	/**
	 * @param $xml
	 * @return array|null
	 */
	public static function toArray($xml): ?array
	{
		if (is_array($xml)) return $xml;
		if (str_starts_with('<', $xml) && str_ends_with('>', $xml)) {
			return self::xmlToArray($xml);
		} else {
			return self::jsonToArray($xml);
		}
	}


	/**
	 * @param string $xml
	 * @return array|null
	 */
	public static function jsonToArray(string $xml): ?array
	{
		return json_decode($xml, true);
	}

	/**
	 * @param string $xml
	 * @return array|null
	 */
	public static function xmlToArray(string $xml): ?array
	{
		if (($data = @simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)) !== false) {
			return json_decode(json_encode($data), TRUE);
		}
		return null;
	}

	/**
	 * @param mixed $json
	 * @return string
	 */
	public static function toJson(mixed $json): string
	{
		if (is_object($json)) {
			$json = get_object_vars($json);
		}
		if (is_array($json)) {
			return json_encode($json, JSON_UNESCAPED_UNICODE);
		}
		$matchQuote = '/(<\?xml.*?\?>)?<([a-zA-Z_]+)>(<([a-zA-Z_]+)><!.*?><\/\4>)+<\/\2>/';
		if (preg_match($matchQuote, $json)) {
			$json = self::xmlToArray($json);
		} else {
			$json = json_decode($json, true);
		}
		if (!is_array($json)) {
			$json = [];
		}
		return json_encode($json, JSON_UNESCAPED_UNICODE);
	}

	/**
	 * @param int $length
	 * @return string
	 *
	 * 随机字符串
	 */
	public static function random(int $length = 20): string
	{
		$res = [];
		$str = 'abcdefghijklmnopqrstuvwxyz';
		$str .= strtoupper($str) . '1234567890';
		for ($i = 0; $i < $length; $i++) {
			$rand = substr($str, rand(0, strlen($str) - 2), 1);
			if (empty($rand)) {
				$rand = substr($str, strlen($str) - 3, 1);
			}
			$res[] = $rand;
		}

		return implode($res);
	}

	/**
	 * @param array $array
	 * @param $key
	 * @param $type
	 * @return string
	 */
	public static function sign(array $array, $key, $type): string
	{
		ksort($array);
		$buff = "";
		foreach ($array as $k => $v) {
			if ($k != "sign" && $v != "" && !is_array($v)) {
				$buff .= $k . "=" . $v . "&";
			}
		}
		$string = trim($buff, "&") . '&key=' . $key;
		if (strtoupper($type) == 'MD5') {
			return strtoupper(md5($string));
		} else {
			return hash_hmac('sha256', $string, $key);
		}
	}

}
